/**
 *  This file is part of MunchLevel.
 *
 *  MunchLevel is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MunchLevel is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with MunchLevel.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.munchlevel;

import java.io.File;
import java.util.Arrays;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

import com.gandulf.guilib.util.Debug;
import com.munchlevel.data.GameInfo;
import com.munchlevel.data.PlayerInfo;
import com.munchlevel.view.CounterView;

public class VictoryActivity extends BaseActivity implements android.view.View.OnClickListener,
		DialogInterface.OnClickListener {

	private ViewFlipper viewFlipper;

	private GestureDetector gestureDetector = new GestureDetector(new MyGestureListener());

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		return gestureDetector.onTouchEvent(event);
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND, WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
		this.setVolumeControlStream(AudioManager.STREAM_MUSIC);

		setContentView(R.layout.victory);

		gestureDetector.setIsLongpressEnabled(false);

		viewFlipper = (ViewFlipper) findViewById(R.id.player_results);

		GameInfo gameInfo = MunchLevelApplication.getInstance().getGameInfo();
		PlayerInfo[] playerInfos = MunchLevelApplication.getInstance().getGameInfo().getPlayer();

		Arrays.sort(playerInfos, PlayerInfo.LEVEL_COMPARATOR);

		PlayerInfo dizzedPlayer = getDizzedPlayer(playerInfos);

		for (int i = 0; i < playerInfos.length; i++) {

			PlayerInfo playerInfo = playerInfos[i];
			View userDetails = getLayoutInflater().inflate(R.layout.victory_user, viewFlipper, false);

			TextView playerName = (TextView) userDetails.findViewById(R.id.tv_playername);
			playerName.setText((i + 1) + ". " + playerInfo.getName());

			CounterView lvlCounter = (CounterView) userDetails.findViewById(R.id.lvl_counter);
			lvlCounter.setValue(playerInfo.getLevel());
			CounterView gearCounter = (CounterView) userDetails.findViewById(R.id.gear_counter);
			gearCounter.setValue(playerInfo.getGear());

			CounterView lvlGainCounter = (CounterView) userDetails.findViewById(R.id.lvl_gain);
			lvlGainCounter.setOnClickListener(this);
			lvlGainCounter.setValue(playerInfo.getLevelGain(), true);
			CounterView lvlLossCounter = (CounterView) userDetails.findViewById(R.id.lvl_loss);
			lvlLossCounter.setValue(-playerInfo.getLevelLoss());
			lvlLossCounter.setOnClickListener(this);
			CounterView gearGainCounter = (CounterView) userDetails.findViewById(R.id.gear_gain);
			gearGainCounter.setValue(playerInfo.getGearGain(), true);
			gearGainCounter.setOnClickListener(this);
			CounterView gearLossCounter = (CounterView) userDetails.findViewById(R.id.gear_loss);
			gearLossCounter.setValue(-playerInfo.getGearLoss());
			gearLossCounter.setOnClickListener(this);

			ImageView profileView = (ImageView) userDetails.findViewById(R.id.iv_profile);
			File file = new File(getCacheDir(), "profile_" + playerInfo.getIndex() + ".jpg");
			if (file.exists()) {
				Debug.verbose("restoring picture for player " + playerInfo.getIndex());
				Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());

				if (bitmap != null) {
					// landscape
					if (bitmap.getWidth() > bitmap.getHeight()) {
						profileView.getLayoutParams().width = getResources().getDimensionPixelSize(R.dimen.photo_long);
						profileView.getLayoutParams().height = getResources()
								.getDimensionPixelSize(R.dimen.photo_short);
					} else { // portrait
						profileView.getLayoutParams().width = getResources().getDimensionPixelSize(R.dimen.photo_short);
						profileView.getLayoutParams().height = getResources().getDimensionPixelSize(R.dimen.photo_long);
					}
					profileView.setImageBitmap(bitmap);
				} else {
					profileView.setVisibility(View.GONE);
				}
			} else {
				profileView.setVisibility(View.GONE);
			}

			LinearLayout medalLayout = (LinearLayout) userDetails.findViewById(R.id.medal_layout);
			if (i == 0) {
				addMedal(R.drawable.medal, medalLayout);
			}
			if (dizzedPlayer == playerInfo) {
				addMedal(R.drawable.medal_dizz, medalLayout);
			}

			MunchLevelApplication.applyFont(playerName, userDetails.findViewById(R.id.lvl_gain_txt),
					userDetails.findViewById(R.id.gear_gain_txt));
			viewFlipper.addView(userDetails);
		}

		if (gameInfo.getPlayers() > 1) {
			viewFlipper.setAnimateFirstView(true);
			viewFlipper.setInAnimation(this, android.R.anim.slide_in_left);
			viewFlipper.setOutAnimation(this, android.R.anim.slide_out_right);
			viewFlipper.setFlipInterval(5000);
			viewFlipper.startFlipping();
		}

		ImageButton share = (ImageButton) findViewById(R.id.medal_share);
		share.setOnClickListener(this);

	}

	private void addMedal(int resourceId, LinearLayout layout) {

		ImageView medal = new ImageView(this);
		medal.setScaleType(ScaleType.CENTER_INSIDE);
		medal.setImageResource(resourceId);
		layout.addView(medal, getResources().getDimensionPixelSize(R.dimen.medal_width), getResources()
				.getDimensionPixelSize(R.dimen.medal_height));

		medal.setOnClickListener(this);

		if (resourceId == R.drawable.medal)
			medal.setId(R.id.medal_win);

		if (resourceId == R.drawable.medal_dizz)
			medal.setId(R.id.medal_dizz);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_menu, menu);
		return super.onCreateOptionsMenu(menu);
	}

	public void share(String subject, String text) {
		final Intent intent = new Intent(Intent.ACTION_SEND);

		intent.setType("text/plain");
		intent.putExtra(Intent.EXTRA_SUBJECT, subject);
		intent.putExtra(Intent.EXTRA_TEXT, text);

		startActivity(Intent.createChooser(intent, getString(R.string.share)));
	}

	public boolean applyTheme() {
		return true;
	}

	@Override
	public void onClick(DialogInterface dialog, int which) {
		if (which == DialogInterface.BUTTON_POSITIVE) {
			setResult(Activity.RESULT_OK);
			finish();
		} else if (which == DialogInterface.BUTTON_NEGATIVE) {
			setResult(Activity.RESULT_CANCELED);
			finish();
		}
	}

	private void showToast(int msg) {
		Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.medal_share:

			GameInfo gameInfo = MunchLevelApplication.getInstance().getGameInfo();

			if (gameInfo.getPlayers() > 1) {
				StringBuilder sb = new StringBuilder();
				for (int i = 1; i < gameInfo.getPlayers(); i++) {
					sb.append(gameInfo.getPlayer(i).getName());
					if (i < gameInfo.getPlayers() - 2)
						sb.append(", ");
					if (i < gameInfo.getPlayers() - 1)
						sb.append(" and ");
				}

				share(getString(R.string.share_title),
						getString(R.string.share_description_multi, gameInfo.getPlayer(0).getName(), sb.toString()));

			} else {
				share(getString(R.string.share_title),
						getString(R.string.share_description_solo, gameInfo.getPlayer(0).getName()));
			}
			break;
		case R.id.lvl_gain:
			showToast(R.string.tooltip_level_gain);
			break;
		case R.id.lvl_loss:
			showToast(R.string.tooltip_level_loss);
			break;
		case R.id.gear_gain:
			showToast(R.string.tooltip_gear_gain);
			break;
		case R.id.gear_loss:
			showToast(R.string.tooltip_gear_loss);
			break;
		case R.id.medal_dizz:
			showToast(R.string.tooltip_medal_dizz);
			break;
		case R.id.medal_win:
			showToast(R.string.tooltip_medal_win);
			break;
		}
	}

	protected PlayerInfo getDizzedPlayer(PlayerInfo[] playerInfos) {
		PlayerInfo dizz = playerInfos[0];
		int dizzLoose1 = dizz.getBonusLoss() * 2 + dizz.getLevelLoss() + dizz.getGearLoss();

		for (PlayerInfo playerInfo : playerInfos) {

			int loose1 = playerInfo.getBonusLoss() * 2 + playerInfo.getLevelLoss() + playerInfo.getGearLoss();

			if (loose1 > dizzLoose1) {
				dizz = playerInfo;
				dizzLoose1 = loose1;
			}

		}

		return dizz;

	}

	private Animation inFromRightAnimation() {

		// Animation inFromRight = new TranslateAnimation(
		/*
		 * Animation inFromRight = new ScaleAnimation(
		 * Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
		 * 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f,
		 * Animation.RELATIVE_TO_PARENT, 0.0f);
		 */
		Animation inFromRight = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF,
				0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);

		inFromRight.setDuration(500);
		inFromRight.setInterpolator(new AccelerateInterpolator());
		return inFromRight;
	}

	private Animation outToLeftAnimation() {
		// Animation outtoLeft = new TranslateAnimation(
		/*
		 * Animation outtoLeft = new
		 * ScaleAnimation(Animation.RELATIVE_TO_PARENT, 0.0f,
		 * Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
		 * 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f);
		 */
		Animation outtoLeft = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
				-1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
		outtoLeft.setDuration(500);
		outtoLeft.setInterpolator(new AccelerateInterpolator());
		return outtoLeft;
	}

	private Animation inFromLeftAnimation() {
		// Animation inFromLeft = new TranslateAnimation(
		/*
		 * Animation inFromLeft = new
		 * ScaleAnimation(Animation.RELATIVE_TO_PARENT, 0.0f,
		 * Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
		 * 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f);
		 */
		Animation inFromLeft = new TranslateAnimation(Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF,
				0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
		inFromLeft.setDuration(500);
		inFromLeft.setInterpolator(new AccelerateInterpolator());
		return inFromLeft;
	}

	private Animation outToRightAnimation() {
		// Animation outtoRight = new TranslateAnimation(
		/*
		 * Animation outtoRight = new
		 * ScaleAnimation(Animation.RELATIVE_TO_PARENT, 0.0f,
		 * Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
		 * 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f);
		 */
		Animation outtoRight = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
				1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
		outtoRight.setDuration(500);
		outtoRight.setInterpolator(new AccelerateInterpolator());
		return outtoRight;
	}

	class MyGestureListener extends SimpleOnGestureListener {

		private static final int SWIPE_MIN_DISTANCE = 120;
		private static final int SWIPE_MAX_OFF_PATH = 250;
		private static final int SWIPE_THRESHOLD_VELOCITY = 200;

		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
			viewFlipper.stopFlipping();
			Debug.verbose("Fling");
			if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
				return false;
			if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
				viewFlipper.setInAnimation(inFromRightAnimation());
				viewFlipper.setOutAnimation(outToLeftAnimation());
				viewFlipper.showNext();
				return true;
			} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
				viewFlipper.setInAnimation(inFromLeftAnimation());
				viewFlipper.setOutAnimation(outToRightAnimation());
				viewFlipper.showPrevious();
				return true;
			}
			return false;
		}

		@Override
		public boolean onSingleTapConfirmed(MotionEvent e) {
			AlertDialog.Builder builder = new AlertDialog.Builder(VictoryActivity.this);
			builder.setTitle(R.string.finish_title);
			builder.setMessage(R.string.finish_description);
			builder.setPositiveButton(R.string.btn_finish, VictoryActivity.this);
			builder.setNegativeButton(R.string.btn_continue, VictoryActivity.this);
			builder.show();
			return true;
		}
	}

}